//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <string.h>
#include <elatypes.h>

/*
 * strrchr()
 *    Like strchr(), but search backwards
 */
EXTERN_C char *  CDECL strrchr(const char *p, int c)
{
#if defined(_x86) && defined(_GNUC)
    register char * ret;
    ASM("movb %%al,%%ah;"
        "movl $0,%0;"
        "1:"
        "lodsb;"
        "cmpb %%ah,%%al;"
        "jne 2f;"
        "leal -1(%%esi),%0;"
        "2:"
        "testb %%al,%%al;"
        "jne 1b"
        :"=&g"(ret)
        :"S"(p), "a"(c));
    return ret;
#elif defined(_arm) && defined(_GNUC)
    register char * ret;
    asm __volatile__(
        "mov r3, #0\n"
        "1:\tldrb r2, [r0], #1\n\t"
        "teq r2, r1\n\t"
        "subeq  r3, r0, #1\n\t"
        "teq r2, #0\n\t"
        "bne 1b\n\t"
        "mov %0, r3\n"
        :"=r"(ret)
        ::"r3");
    return ret;
//#elif defined(_mips)
//    asm __volatile__("break 0");
#else
    char *q = 0, c2;

    do {
        c2 = *p++;
        if (c == c2) {
            q = (char *)p;
        }
    } while (c2);
    return(q ? (q-1) : 0);
#endif
}

/*
 * wcsrchr()
 *    strrchr() wild-char version
 */
EXTERN_C wchar_t *  CDECL wcsrchr(const wchar_t *p, int c)
{

#if defined(_x86) && defined(_GNUC)
    register wchar_t * ret;
    ASM("movw %%ax,%%bx;"
        "movl $0,%0;"
        "1:"
        "lodsw;"
        "cmpw %%bx,%%ax;"
        "jne 2f;"
        "leal -2(%%esi),%0;"
        "2:"
        "testw %%ax,%%ax;"
        "jne 1b;"
        :"=&g"(ret)
        :"S"(p), "a"(c)
        :"bx");
    return ret;
#else
    wchar_t *q = 0, c2;

    do {
        c2 = *p++;
        if (c == c2) {
            q = (wchar_t *)p;
        }
    } while (c2);
    return(q ? (q - 1) : 0);
#endif
}
